<template>
  <slot :data="data"></slot>
  <div class="text-center" v-if="status === 'loaded' && data.length === 0">
    Empty
  </div>
  <div class="text-center" v-if="status === 'loading'">Loading...</div>
  <div class="text-center" v-if="status === 'noMore'">No more data</div>
  <div class="text-center text-red-500" v-if="status === 'error'">
    Error loading data
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from "vue";
import { onReachBottom } from "@dcloudio/uni-app";

const props = defineProps({
  pageSize: {
    type: Number,
    default: 20,
  },
  callApi: {
    type: Function,
    required: true,
  },
  extramParams: {
    type: Object,
    default: () => ({}),
  },
});

const data = ref<any[]>([]);
const page = ref(0);

const status = ref<"init" | "loading" | "loaded" | "noMore" | "error">("init");

const loadData = async () => {
  if (!props.callApi) {
    console.warn("callApi is not defined");
    return;
  }
  if (!["init", "loaded"].includes(status.value)) {
    return;
  }
  status.value = "loading";
  page.value++;
  try {
    const res = await props.callApi({
      page: page.value,
      pageSize: props.pageSize,
      ...props.extramParams,
    });

    const { data: resData } = res;
    data.value = [...data.value, ...resData];
    if (resData.length < props.pageSize) {
      status.value = "noMore";
    } else {
      status.value = "loaded";
    }
  } catch (e) {
    status.value = "error";
  }
};

const reInit = () => {
  data.value = [];
  page.value = 0;
  status.value = "init";
};

watch(
  () => props.extramParams,
  () => {
    reInit();
    loadData();
  },
  {
    immediate: true,
    deep: true,
  }
);

onReachBottom(() => {
  loadData();
});
</script>
